package iagovsothello.online.client;
import iagovsothello.ai.*;
import iagovsothello.ai.heuristics.*;
import iagovsothello.core.GameState;
import iagovsothello.core.OthelloInterface;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.swing.*;


/**
* This code was edited or generated using CloudGarden's Jigloo
* SWT/Swing GUI Builder, which is free for non-commercial
* use. If Jigloo is being used commercially (ie, by a corporation,
* company or business for any purpose whatever) then you
* should purchase a license for each developer using Jigloo.
* Please visit www.cloudgarden.com for details.
* Use of Jigloo implies acceptance of these licensing terms.
* A COMMERCIAL LICENSE HAS NOT BEEN PURCHASED FOR
* THIS MACHINE, SO JIGLOO OR THIS CODE CANNOT BE USED
* LEGALLY FOR ANY CORPORATE OR COMMERCIAL PURPOSE.
*/
/**
 * Interfaccia grafica per avviare rapidamente una nuova partita umano contro umano o contro pc, con a disposizione
 * dei livelli di difficolt� predeterminati
 *
 */
public class QuickGameWindowClient extends javax.swing.JFrame {
	
	private static final long serialVersionUID = -705867311481750263L;
	private MainWindowClient mainWindow;
	private JLabel labelChooseColor;
	private JLabel labelCurrentGamesLeft;
	private JLabel labelGamesLeft;

	private JRadioButton radioButtonPlayer1;
	private JRadioButton radioButtonFutile;
	private JRadioButton radioButtonEasy;
	private JButton buttonStart;
	private JRadioButton radioButtonImpossibru;
	private JRadioButton radioButtonHard;
	private JRadioButton radioButtonMedium;
	private JLabel labelDifficulty;
	private JRadioButton radioButtonPlayer2;

	private ButtonGroup buttonGroupHumanAI;
	private ButtonGroup buttonGroupPlayer;
	private ButtonGroup buttonGroupDifficulty;
	
	private String ID;
	private String gamesLeft;

	private String addressIPServer;//sulla macchina dove DOVREBBE andare l'indirizzo sara' 192.168.100.53


	private static int portServer = 7777;


	public static final int PORT = 7777;

	
	public QuickGameWindowClient(MainWindowClient mainWindow) {
		super();
		
		this.mainWindow = mainWindow;
		
		initGUI();
	}
	
	private void initGUI() {
		GridBagLayout thisLayout = new GridBagLayout();
			setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
			thisLayout.rowWeights = new double[] {0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
			thisLayout.rowHeights = new int[] {71, 20, 30, 30, 30, 30, 30, 30, 50};
			thisLayout.columnWeights = new double[] {0.0, 0.0, 0.1, 0.0, 0.0};
			thisLayout.columnWidths = new int[] {30, 200, 20, 110, 80};
			getContentPane().setLayout(thisLayout);
			this.setTitle("Partita rapida");
			getContentPane().setBackground(new java.awt.Color(192,192,192));
			this.setResizable(false);

			radioButtonPlayer1 = new JRadioButton();
			getContentPane().add(radioButtonPlayer1, new GridBagConstraints(1, 4, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 4, 0, 0), 0, 0));
			radioButtonPlayer1.setText("Gioca come giocatore bianco");

			radioButtonPlayer2 = new JRadioButton();
			getContentPane().add(radioButtonPlayer2, new GridBagConstraints(1, 5, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 4, 0, 0), 0, 0));
			radioButtonPlayer2.setText("Gioca come giocatore nero");

			labelDifficulty = new JLabel();
			getContentPane().add(labelDifficulty, new GridBagConstraints(3, 2, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
			labelDifficulty.setText("Scegli la difficolta' di gioco!");
			labelDifficulty.setFont(new java.awt.Font("Dialog",1,14));

			radioButtonFutile = new JRadioButton();
			getContentPane().add(radioButtonFutile, new GridBagConstraints(3, 3, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
			radioButtonFutile.setText("Principiante");

			radioButtonEasy = new JRadioButton();
			getContentPane().add(radioButtonEasy, new GridBagConstraints(3, 4, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
			radioButtonEasy.setText("Apprendista");

			radioButtonMedium = new JRadioButton();
			getContentPane().add(radioButtonMedium, new GridBagConstraints(3, 5, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
			radioButtonMedium.setText("Intermedio");

			radioButtonHard = new JRadioButton();
			getContentPane().add(radioButtonHard, new GridBagConstraints(3, 6, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
			radioButtonHard.setText("Esperto");

			radioButtonImpossibru = new JRadioButton();
			getContentPane().add(radioButtonImpossibru, new GridBagConstraints(3, 7, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
			radioButtonImpossibru.setText("Molto esperto");

			buttonStart = new JButton();
			getContentPane().add(buttonStart, new GridBagConstraints(4, 8, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(4, 4, 4, 4), 0, 0));
			buttonStart.setText("Inizia");
			{
				labelGamesLeft = new JLabel();
				getContentPane().add(labelGamesLeft, new GridBagConstraints(1, 0, 3, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
				labelGamesLeft.setText("Partite di torneo rimanenti:");
				labelGamesLeft.setFont(new java.awt.Font("Dialog",1,14));
			}
			{
				labelCurrentGamesLeft = new JLabel();
				getContentPane().add(labelCurrentGamesLeft, new GridBagConstraints(4, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
				
				gamesLeft = mainWindow.getGamesLeft();
				labelCurrentGamesLeft.setText(gamesLeft);
				labelCurrentGamesLeft.setFont(new java.awt.Font("Dialog",0,14));

			}
			{
				labelChooseColor = new JLabel();
				getContentPane().add(labelChooseColor, new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
				labelChooseColor.setText("Scegli il colore!");
				labelChooseColor.setFont(new java.awt.Font("Dialog",1,14));
			}
			buttonStart.addActionListener(new StartActionListener());
			
			buttonGroupHumanAI = new ButtonGroup();

			buttonGroupPlayer = new ButtonGroup();
			
			buttonGroupPlayer.add(radioButtonPlayer1);
			
			radioButtonPlayer1.setSelected(true);
			radioButtonPlayer1.setBackground(new java.awt.Color(192,192,192));
			
			buttonGroupPlayer.add(radioButtonPlayer2);
			radioButtonPlayer2.setBackground(new java.awt.Color(192,192,192));
			
			buttonGroupDifficulty = new ButtonGroup();
			buttonGroupDifficulty.add(radioButtonFutile);
			
			radioButtonFutile.setSelected(true);
			radioButtonFutile.setBackground(new java.awt.Color(192,192,192));
			
			buttonGroupDifficulty.add(radioButtonEasy);
			radioButtonEasy.setBackground(new java.awt.Color(192,192,192));
			
			buttonGroupDifficulty.add(radioButtonMedium);
			radioButtonMedium.setBackground(new java.awt.Color(192,192,192));
			
			buttonGroupDifficulty.add(radioButtonHard);
			radioButtonHard.setBackground(new java.awt.Color(192,192,192));
			
			buttonGroupDifficulty.add(radioButtonImpossibru);
			radioButtonImpossibru.setBackground(new java.awt.Color(192,192,192));

			pack();
			this.setSize(534, 319);
			
			update();
	}
	

	
	private void start()
	{
		Agent other = null;
		
	
		
		boolean readyToPlay = false;
		
		
		if (radioButtonFutile.isSelected())
		{	
			other = new Greedy();
			mainWindow.setDifficultyLevel(1);
			readyToPlay = true;
			try {
				sendStartGameInfo(1);
			} catch (UnknownHostException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		else if (radioButtonEasy.isSelected())
		{
			other = new HABPruning(2,new HeuristicFunctionMobility());
			mainWindow.setDifficultyLevel(2);
			readyToPlay = true;
			try {
				sendStartGameInfo(2);
			} catch (UnknownHostException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			

		}
		else if (radioButtonMedium.isSelected())
		{
			int response = JOptionPane.showOptionDialog(this, "ATTENZIONE: Hai selezionato difficoltà INTERMEDIO! Questa partita sarà considerata valida per il torneo!\n Vuoi davvero giocare una partita contro IAgo INTERMEDIO?",
					 "ATTENZIONE!", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, null, null);
			
			if(response == JOptionPane.YES_OPTION){
					other = new HABPruning(2,new HeuristicFunctionCorners());
					mainWindow.setDifficultyLevel(3);
					readyToPlay = true;
					try {
						sendStartGameInfo(3);
					} catch (UnknownHostException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
			}

		}
		else if (radioButtonHard.isSelected())
		{
			int response = JOptionPane.showOptionDialog(this, "ATTENZIONE: Hai selezionato difficoltà ESPERTO! Questa partita sarà considerata valida per il torneo!\n Vuoi davvero giocare una partita contro IAgo ESPERTO?",
					 "ATTENZIONE!", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, null, null);
			if(response == JOptionPane.YES_OPTION){
				other = new HABPruning(3,new HeuristicFunctionEdge());
				mainWindow.setDifficultyLevel(4);
				readyToPlay = true;
				try {
					sendStartGameInfo(4);
				} catch (UnknownHostException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}
		}
		else if (radioButtonImpossibru.isSelected())
		{
			int response = JOptionPane.showOptionDialog(this, "ATTENZIONE: Hai selezionato difficoltà MOLTO ESPERTO! Questa partita sarà considerata valida per il torneo!\n Vuoi davvero giocare una partita contro IAgo MOLTO ESPERTO?",
					 "ATTENZIONE!", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, null, null);
			if(response == JOptionPane.YES_OPTION){
				other = new HABPruning(5,new HeuristicFunctionEdgeStability());
				mainWindow.setDifficultyLevel(5);
				readyToPlay = true;
				try {
					sendStartGameInfo(5);
				} catch (UnknownHostException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}
	
		}
		
		
		if (radioButtonPlayer1.isSelected())
		{
			mainWindow.setPlayer1(null);
			mainWindow.setPlayer2(other);
		}
		else
		{
			mainWindow.setPlayer2(null);
			mainWindow.setPlayer1(other);

		}
		
		if(readyToPlay){
			//stato iniziale del gioco con 4 pedine al centro
			GameState startingState = GameState.createStartingState(8);
			
			//inserimento dello stato iniziale nella finestra di gioco
			
			mainWindow.startGame(startingState, 8, false);
			mainWindow.nextMove();
			dispose();
		}
	}
	
	private void update()
	{
		
		boolean enoughGamesLeft;
		
		if(Integer.parseInt(gamesLeft) <= 0)
			enoughGamesLeft = false;
		else
			enoughGamesLeft = true;
		
		
		radioButtonMedium.setEnabled(enoughGamesLeft);
		radioButtonHard.setEnabled(enoughGamesLeft);
		radioButtonImpossibru.setEnabled(enoughGamesLeft);
	}
	
	private void sendStartGameInfo(int difficultyLevel) throws UnknownHostException, IOException{
		
		Socket socket = new Socket(addressIPServer, portServer);

		PrintWriter out = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8"));
		BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));

		/*Pacchetto uscita:
		 * start game
		 * ID
		 * difficolt� (da 1 a 5)
		 */
		
		/*Pacchetto ingresso dal server
		 * ACK
		 * codice sicurezza partita
		 * numero di partite rimanenti
		 * 
		 * OPPURE
		 * NACK
		 * codice errore
		 */
		

		out.println("startGame");
		out.println(ID);
		out.println(difficultyLevel);
		out.flush();
		
		String status = in.readLine();
		
		
		if (status.equals("NACK"))
		{
			System.out.println("CLIENT: ricevuto NACK dal server\n");
			String errorCode = in.readLine();
			if(errorCode.equals("2"))
				JOptionPane.showMessageDialog(null, "ATTENZIONE: hai esaurito il numero di partite disponibili!");
			else if(errorCode.equals("3"))
				JOptionPane.showMessageDialog(null, "ATTENZIONE: non sei autorizzato a giocare!");
			else if(errorCode.equals("1"))
				JOptionPane.showMessageDialog(null, "ATTENZIONE: non sei iscritto al torneo!");

		}
		else if (status.equals("ACK")){
			System.out.println("CLIENT: ricevuto ACK dal server prima della partita\n");
			
			String securityGameCode = in.readLine();
			String gamesLeft = in.readLine();

			mainWindow.setGamesLeft(gamesLeft);
			mainWindow.setSecurityGameCode(securityGameCode);
			labelCurrentGamesLeft.setText(gamesLeft);
			System.out.println("CLIENT: sono rimaste "+ gamesLeft + "partite\n");

			
		}	
		socket.close();			
		
	}
	
	public String getID() {
		return ID;
	}

	public void setID(String iD) {
		ID = iD;
	}
	
	private class UpdateActionListener implements ActionListener {

		public void actionPerformed(ActionEvent evt) 
		{
			update();
		}
	}
	
	private class StartActionListener implements ActionListener {
		
		public void actionPerformed(ActionEvent evt) 
		{
			start();
		}
	}
	public void setAddressIPServer(String addressIPServer) {
		this.addressIPServer = addressIPServer;
	}
}
